package com.kingdee.jdy.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import java.util.Map.Entry;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.DefaultHttpParams;
import org.apache.commons.httpclient.params.HttpClientParams;

/**
 * 
 * <p>
 * 后台Http操作工具类
 * <p>
 * <p>
 * 金蝶移动互联有限公司版权所有
 * </p>
 * 
 * @author bruce_yang
 * @created 2008-11-11 上午10:01:32
 * @version $Id: HttpUtil.java 64252 2010-01-19 03:15:35Z zach $
 */
public class HttpUtil {

	// private static Logger LOG = Logger.getLogger(HttpUtil.class);


	private static String LINE_SEPARATOR = System.getProperty("line.separator");

	private static final String[] IGNORE_HEADERS = { "content-length", "accept-encoding" };

	private HttpClient httpClient = null;

	private Map<String, String> parameters = new HashMap<String, String>();

	private Map<String, String> headers = new HashMap<String, String>();

	private  int TIMEOUT_TIME = 30000;

	public void setTIMEOUT_TIME(int timeout_time) {
		TIMEOUT_TIME = timeout_time;
	}

	public HttpUtil() {}

	public HttpUtil(String token, String accountId, String groupName) {
		addParameter("access_token", token);
		addHeader("accountId", accountId);
		addHeader("groupName", groupName);
	}


	public HttpUtil(int DEFAULT_TIME_OUT) {
		TIMEOUT_TIME = DEFAULT_TIME_OUT;
	}

	public void addParameter(String name, String value) {
		parameters.put(name, value);
	}

	public void removeParameter(String name) {
		parameters.remove(name);
	}

	public void addHeader(String name, String value) {
		headers.put(name, value);
	}

	public String post(String url) throws HttpException, IOException {

		if (httpClient == null) createClient();

		PostMethod method = new PostMethod(url);
		method.getParams().setSoTimeout(TIMEOUT_TIME);
		addParameters(method);
		addHeaders(method);

		return getRequestString(method, url);
	}

	public String post(String url, int timeOut) throws HttpException, IOException {

		if (httpClient == null) createClient();

		PostMethod method = new PostMethod(url);
		method.getParams().setSoTimeout(timeOut);
		addParameters(method);
		addHeaders(method);

		return getRequestString(method, url);
	}

	public String post(String url, String charset) throws HttpException, IOException {

		if (httpClient == null) createClient();
		PostMethod method = new PostMethod(url);
		method.getParams().setSoTimeout(TIMEOUT_TIME);
		if (charset.equalsIgnoreCase("UTF-8")) addUTF8Parameters(method);
		else
			addParameters(method);
		addHeaders(method);

		return getRequestString(method, url);
	}

	public String post(String url, String charset, int timeOut) throws HttpException, IOException {

		if (httpClient == null) createClient();
		PostMethod method = new PostMethod(url);
		method.getParams().setSoTimeout(timeOut);
		if (charset.equalsIgnoreCase("UTF-8")) addUTF8Parameters(method);
		else
			addParameters(method);
		addHeaders(method);

		return getRequestString(method, url);
	}

	public String get(String url) throws HttpException, IOException {

		if (httpClient == null) createClient();

		GetMethod method = new GetMethod(url);
		method.getParams().setSoTimeout(TIMEOUT_TIME);
		addHeaders(method);

		return getRequestString(method, url);
	}

	public String get(String url, int timeOut) throws HttpException, IOException {

		if (httpClient == null) createClient();

		GetMethod method = new GetMethod(url);
		method.getParams().setSoTimeout(timeOut);
		addHeaders(method);

		return getRequestString(method, url);
	}

	private String getRequestString(HttpMethod method, String url) throws UnsupportedEncodingException, IOException {
		StringBuilder buffer = new StringBuilder();
		try {
			int statusCode = httpClient.executeMethod(method);
			if (statusCode != HttpStatus.SC_OK) throw new IOException(url + ":" + statusCode);

			BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "utf-8"));
			String line;
			while ((line = reader.readLine()) != null)
				buffer.append(line).append(LINE_SEPARATOR);
		} finally {
			if (method != null) method.releaseConnection();
		}
		return buffer.toString();
	}

	private void addHeaders(HttpMethod method) {
		out: for (String key : headers.keySet()) {
			for (String ignore : IGNORE_HEADERS)
				if (ignore.equals(key)) continue out;
			String value = headers.get(key);
			method.addRequestHeader(key, value);
		}
	}

	private void addParameters(PostMethod method) throws UnsupportedEncodingException {
		for (String key : parameters.keySet()) {
			String value = parameters.get(key);
			value = new String(value.getBytes("utf-8"), "ISO8859-1");
			method.addParameter(key, value);
		}
	}

	private void addUTF8Parameters(PostMethod method) {
		for (String key : parameters.keySet()) {
			String value = parameters.get(key);
			method.addParameter(key, value);
		}
	}

	private void createClient() {
		httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT_TIME);
		httpClient.getHttpConnectionManager().getParams().setSoTimeout(TIMEOUT_TIME);

		HttpClientParams params = httpClient.getParams();
		params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

		addHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1)");
		addHeader("Accept-Language", "zh-cn,zh;q=0.5");
	}



	public static JSONObject doPost(String url, Map<String,Object> urlParam, Map<String,Object> headerParam, String bodyParam) throws Exception {
		JSONObject ret = null;
		HttpClient httpClient = new HttpClient();
        HttpClientParams params = httpClient.getParams();
        params.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);

        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);
		PostMethod postMethod = new PostMethod(url);

        if (headerParam != null && headerParam.size() > 0) {
            for (Entry<String, Object> header : headerParam.entrySet()) {
                postMethod
                    .setRequestHeader(header.getKey(), header.getValue() == null ? "" : header.getValue().toString());
            }
        }
        postMethod.setRequestHeader("Content-type", "application/json; charset=UTF-8");

        if (urlParam != null && urlParam.size() > 0) {
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<>();
            for (Entry<String, Object> entry : urlParam.entrySet()) {
                nameValuePairs.add(
                    new NameValuePair(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString()));
            }
            postMethod.setQueryString(nameValuePairs.toArray(new NameValuePair[urlParam.size()]));
        }

        if (bodyParam != null) {
			postMethod.setRequestBody(bodyParam);
		}

		//发送请求
        int status = httpClient.executeMethod(postMethod);
        String responseText = postMethod.getResponseBodyAsString();
        System.out.println("访问接口: " + postMethod.getURI() + "  body参数: " + bodyParam + "\n 返回: " + responseText);
        if (responseText != null) {
            ret = JSON.parseObject(responseText);
        }
        postMethod.releaseConnection();

		return ret;
	}

	public static JSONObject doGet(String url, Map<String,Object> urlParam, Map<String,Object> headerParam) throws Exception {
		JSONObject ret = null;
		HttpClient httpClient = new HttpClient();
        HttpClientParams params = httpClient.getParams();
        params.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);

        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);
		HttpMethod httpMethod = new GetMethod(url);

		if (headerParam != null && headerParam.size() > 0) {
            for (Entry<String, Object> header : headerParam.entrySet()) {
                httpMethod
                    .setRequestHeader(header.getKey(), header.getValue() == null ? "" : header.getValue().toString());
            }
        }

        if (urlParam != null && urlParam.size() > 0) {
            ArrayList<NameValuePair> nameValuePairs = new ArrayList<>();
            for (Entry<String, Object> entry : urlParam.entrySet()) {
                nameValuePairs.add(
                    new NameValuePair(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString()));
            }
            httpMethod.setQueryString(nameValuePairs.toArray(new NameValuePair[urlParam.size()]));
        }

        //发送请求
        int status = httpClient.executeMethod(httpMethod);
        String responseText = httpMethod.getResponseBodyAsString();
        System.out.println("访问接口: " + httpMethod.getURI() + "\n返回: " + responseText);
        if (responseText != null) {
            ret = JSON.parseObject(responseText);
        }
        httpMethod.releaseConnection();

		return ret;
	}
}
